package com.hgd.security.evp.common.util;

import org.springframework.beans.BeanUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * @author 尚村山夫
 *
 */
public class BeanUtil extends BeanUtils{

	public static final List<String> defaultSkipFields;
	
	static {
	    defaultSkipFields=new ArrayList<>();
		defaultSkipFields.add("crtTime");
		defaultSkipFields.add("crtUserId");
		defaultSkipFields.add("crtUserName");
		defaultSkipFields.add("updUserId");
		defaultSkipFields.add("updUserName");
		defaultSkipFields.add("updTime");
		defaultSkipFields.add("tenantId");
	}

	/**
	 * 判断一个对象是否为NULL，如果是，则返回一个新对象
	 * @param t
	 * @param clazz
	 * @return
	 */
	public static <T> T checkNullObject(T t, Class<T> clazz) {
		if (EmptyUtil.isEmpty(t)) {
			try {
				return clazz.newInstance();
			} catch (InstantiationException | IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return t;
	}

	/**
	 * 将clazz类中，包含skipFields内的属性去除掉
	 * 该方法通常用于：
	 * 在进行查询数据库中指定字段时，如果不被查询的字段较少，可使用该方法将不进行查询的字段去除掉
	 *
	 * @author By尚
	 * @param clazz
	 * @param skipFields
	 * @return clazz中去除skipFields中属性后的属性数组
	 */
	public static String[] skipFields(Class<?> clazz, String... skipFields) {
		Field[] declaredFields = clazz.getDeclaredFields();

		List<String> originFieldsList = new ArrayList<>();
		if (EmptyUtil.isNotEmpty(declaredFields)) {
			for (Field field : declaredFields) {
				originFieldsList.add(field.getName());
			}
		}

		List<String> skipFieldsList;
		if (skipFields == null) {
			skipFieldsList = Collections.singletonList("");
		} else {
			skipFieldsList = Arrays.asList(skipFields);
		}

		originFieldsList.removeAll(skipFieldsList);

        return originFieldsList.toArray(new String[originFieldsList.size()]);
	}

    /**
     * 如果source对象中与target对象中具有相同的属性，则将source对象的该属性值复制到target对象中<br/>
     * 对于不相同的属性则进行忽略<br/>
     *
     * @author By尚
     * @param source
     *            源对象
     * @param clazz
     *            目标对象实例
     * @return 目标对象
     */
    public static <T> T copyBeanNew(Object source, Class<T> clazz) {
        try {
            T t = clazz.newInstance();
            BeanUtils.copyProperties(source, t);
            return t;
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 如果source是list集合，则将其复制一份<br/>
     * 复制品中的元素是与source元素中属性值相同的新元素<br/>
     * 对于不相同的属性则进行忽略<br/>
     * 如果source对象不是list集合，则返回空集合
     *
     * @author By尚
     * @param source
     *            源对象
     * @return 目标对象(ArrayList实例)
     */
    public static <T> List<T> copyBeanListNew(Object source, Class<T> clazz) {
        List<T> result = new ArrayList<>();
        if (source instanceof List) {
            List source1 = (List) source;
            for (int i = 0; i < source1.size(); i++) {
                T t = copyBeanNew(source1.get(i), clazz);
                result.add(t);
            }
        }
        return result;
    }
}
